package com.access.boot.autoconfigure.apisdk.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author Yangzhen
 * @date 2022/6/2 16:31
 * @since 1.0.0
 */
public class JdkDynamicAopProxy implements InvocationHandler {

    // 包装被代理的对象，每个被代理的对象都有一组Advice
    private AdvisedSupport advised;

    public JdkDynamicAopProxy(AdvisedSupport advised) {
        this.advised = advised;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), advised.getProxiedInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        // 获取被代理的对象
        Object target = advised.getTarget();
        // 获取 Method 匹配的所有 Advice
        List<Object> chain = this.advised.getInterceptors(method, target.getClass());

        Object retVal;

        if (chain.isEmpty()) {
            // 没有 Advice，直接执行 Method
            retVal = method.invoke(target, args);
        } else {
            // 递归调用 Advice
            ReflectiveMethodInvocation reflectiveMethodInvocation = new ReflectiveMethodInvocation(proxy, target, method, args, chain);
            retVal = reflectiveMethodInvocation.proceed();
        }
        return retVal;
    }
}
